#ifndef __norflash_H
#define __norflash_H

#include "stm32f1xx.h"

/* -------------------------------------------- NORFLASH引脚定义 -------------------------------------------- */

#define NORFLASH_CS_GPIO_PORT           GPIOA
#define NORFLASH_CS_GPIO_PIN            GPIO_PIN_2
#define NORFLASH_CS_GPIO_CLK_ENABLE()   do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PA口时钟使能 */

/* ------------------------------------------- NORFLASH控制宏定义 ------------------------------------------- */

/* NORFLASH片选信号 */
#define NORFLASH_CS(x)      do{ x ? \
                                  HAL_GPIO_WritePin(NORFLASH_CS_GPIO_PORT, NORFLASH_CS_GPIO_PIN, GPIO_PIN_SET) : \
                                  HAL_GPIO_WritePin(NORFLASH_CS_GPIO_PORT, NORFLASH_CS_GPIO_PIN, GPIO_PIN_RESET); \
                            }while(0)

/* -------------------------------------------- FLASH芯片ID定义 -------------------------------------------- */

#define W25Q80      0XEF13          /* W25Q80   芯片ID - 1MB容量 */
#define W25Q16      0XEF14          /* W25Q16   芯片ID - 2MB容量 */
#define W25Q32      0XEF15          /* W25Q32   芯片ID - 4MB容量 */
#define W25Q64      0XEF16          /* W25Q64   芯片ID - 8MB容量 */
#define W25Q128     0XEF17          /* W25Q128  芯片ID - 16MB容量 */
#define W25Q256     0XEF18          /* W25Q256  芯片ID - 32MB容量，支持4字节地址 */
#define BY25Q64     0X6816          /* BY25Q64  芯片ID - 8MB容量 */
#define BY25Q128    0X6817          /* BY25Q128 芯片ID - 16MB容量 */
#define NM25Q64     0X5216          /* NM25Q64  芯片ID - 8MB容量 */
#define NM25Q128    0X5217          /* NM25Q128 芯片ID - 16MB容量 */

/* -------------------------------------------- SPI FLASH指令集 -------------------------------------------- */

#define FLASH_WriteEnable           0x06    /* 写使能指令 */
#define FLASH_WriteDisable          0x04    /* 写禁止指令 */
#define FLASH_ReadStatusReg1        0x05    /* 读状态寄存器1 */
#define FLASH_ReadStatusReg2        0x35    /* 读状态寄存器2 */
#define FLASH_ReadStatusReg3        0x15    /* 读状态寄存器3 */
#define FLASH_WriteStatusReg1       0x01    /* 写状态寄存器1 */
#define FLASH_WriteStatusReg2       0x31    /* 写状态寄存器2 */
#define FLASH_WriteStatusReg3       0x11    /* 写状态寄存器3 */
#define FLASH_ReadData              0x03    /* 标准读数据指令 */
#define FLASH_FastReadData          0x0B    /* 快速读数据指令 */
#define FLASH_FastReadDual          0x3B    /* 双线快速读指令 */
#define FLASH_FastReadQuad          0xEB    /* 四线快速读指令 */
#define FLASH_PageProgram           0x02    /* 页编程指令(最大256字节) */
#define FLASH_PageProgramQuad       0x32    /* 四线页编程指令 */
#define FLASH_BlockErase            0xD8    /* 块擦除指令(64KB) */
#define FLASH_SectorErase           0x20    /* 扇区擦除指令(4KB) */
#define FLASH_ChipErase             0xC7    /* 整片擦除指令 */
#define FLASH_PowerDown             0xB9    /* 进入掉电模式 */
#define FLASH_ReleasePowerDown      0xAB    /* 退出掉电模式 */
#define FLASH_DeviceID              0xAB    /* 读设备ID */
#define FLASH_ManufactDeviceID      0x90    /* 读制造商和设备ID */
#define FLASH_JedecDeviceID         0x9F    /* 读JEDEC ID */
#define FLASH_Enable4ByteAddr       0xB7    /* 使能4字节地址模式 */
#define FLASH_Exit4ByteAddr         0xE9    /* 退出4字节地址模式 */
#define FLASH_SetReadParam          0xC0    /* 设置读参数 */
#define FLASH_EnterQPIMode          0x38    /* 进入QPI模式 */
#define FLASH_ExitQPIMode           0xFF    /* 退出QPI模式 */

/* -------------------------------------------- 全局变量声明 ------------------------------------------------ */

extern uint16_t norflash_TYPE;      /* 当前FLASH芯片型号 */

/* -------------------------------------------- 函数声明 ---------------------------------------------------- */

/* 内部静态函数声明 */
static void norflash_wait_busy(void);                                               /* 等待芯片空闲 */
static void norflash_send_address(uint32_t address);                                /* 发送地址(支持3/4字节) */
static void norflash_write_page(uint8_t *pbuf, uint32_t addr, uint16_t datalen);    /* 页写入(256字节内) */
static void norflash_write_nocheck(uint8_t *pbuf, uint32_t addr, uint16_t datalen); /* 无擦除检查写入 */

/* 初始化与配置函数 */
void norflash_init(void);           /* 初始化NORFLASH模块 */
uint16_t norflash_read_id(void);    /* 读取FLASH芯片ID */

/* 状态控制函数 */
void norflash_write_enable(void);                   /* 使能写操作 */
uint8_t norflash_read_sr(uint8_t regno);            /* 读取状态寄存器 */
void norflash_write_sr(uint8_t regno,uint8_t sr);   /* 写状态寄存器 */

/* 擦除操作函数 */
void norflash_erase_chip(void);             /* 整片擦除 */
void norflash_erase_sector(uint32_t saddr); /* 扇区擦除(4KB单位) */

/* 读写操作函数 */
void norflash_read(uint8_t *pbuf, uint32_t addr, uint16_t datalen); /* 读取数据 */
void norflash_write(uint8_t *pbuf, uint32_t addr, uint16_t datalen);/* 写入数据(带擦除) */

/* 测试函数 */
uint8_t norflash_test(void);  /* NORFLASH读写测试函数 */

#endif
